#include <sys/epoll.h>
#include <unistd.h>

#include <iostream>
#include <vector>

#include "../ConnectMsg.h"
#include "../unity.h"

#include "TestClient.h"

using std::cout;
using std::endl;
using std::vector;

const int CLIENT_NUM = 20;
const int CONNECTION_NUM = 2000;

int main()
{
	vector<long> readTime,writeTime;
	int epfd = epoll_create(1024);
	if (epfd == -1)
	{
		errorExit("epoll_create() failed");
	}

	epoll_event events[1024];

	ClientProcess* clients[CLIENT_NUM];
	// 创建连接
	for (int i = 0; i < CLIENT_NUM; ++i)
	{
		clients[i] = new TestClient();
		int clientfd = clients[i]->connect("127.0.0.1",19877); 
		if (clientfd < 0)
		{
			errorLog("create client socket failed!");
			continue;
		}

		// 注册事件
		epoll_event ev;
		ev.events = EPOLLOUT|EPOLLET;
		ev.data.ptr = clients[i];
		epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, &ev);
	}

	size_t count = 0;

	long start, end;
	start = getTime();

	for(;count < CONNECTION_NUM;)
	{
		int num = epoll_wait(epfd, events, 1024, 500);

		for (int i = 0; i < num; ++i)
		{
			TestClient* data = (TestClient*)events[i].data.ptr;
			if (events[i].events & EPOLLOUT)
			{
				long begin = getTime();
				int retVal= data->writeProcess(NULL);
				long end = getTime();
				writeTime.push_back(end-begin);
				if (retVal >= 0)
				{
					// 写成功，注册读事件
					epoll_event ev;
					ev.data.ptr = data;
					ev.events = EPOLLIN|EPOLLET;
					epoll_ctl(epfd, EPOLL_CTL_MOD, data->getfd(), &ev);
				}
			}
			if (events[i].events & EPOLLIN)
			{
				long begin = getTime();
				int result = data->readProcess(NULL);
				long end = getTime();
				readTime.push_back(end-begin);
				if ( result > 0)
				{
					++count;
					epoll_event ev;
					ev.data.ptr = data;
					ev.events = EPOLLOUT|EPOLLET;
					epoll_ctl(epfd, EPOLL_CTL_MOD, data->getfd(), &ev);
				}
			}
		}
	}	

	end = getTime();

	for (int i = 0; i< CLIENT_NUM; ++i)
	{
		clients[i]->close();
		delete clients[i];
	}
	//sleep(60);

	long max=0,min=999999999,sum=0;
	for (auto iter = readTime.begin(); iter != readTime.end();++iter)
	{
		if (*iter > max)
			max = *iter;
		if (*iter < min)
			min = *iter;
		sum += *iter;
	}
	cout << "Read: max:" << max << " min: " << min << " size: " 
		 << readTime.size() << " avg: " << sum/readTime.size()
		 << " sum: "<< sum << endl;
	max=0,min=999999999,sum=0;
	for (auto iter = writeTime.begin(); iter != writeTime.end();++iter)
	{
		if (*iter > max)
			max = *iter;
		if (*iter < min)
			min = *iter;
		sum += *iter;
	}
	cout << "Write: max:" << max << " min: " << min << " size: " 
		 << writeTime.size() << " avg: " << sum/writeTime.size()
		 << " sum: "<< sum << endl;

	long mstime = (end - start) / 1000;
	cout << "Used time: " << mstime << "ms" << endl;
	cout << "Connection num: " << CLIENT_NUM << endl;
	cout << "Total request: " << count << endl;
	cout << "Request per sec: " << count / (1.0*mstime/1000) << endl;
}
